home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1996 / MacHack 1996.toast / Hacks / Hacks ’95 / Closure / Sources / GX Graphics Libraries / offscreen library.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-24  |  10.8 KB  |  370 lines  |  [TEXT/MMCC]

  1. /* graphics libraries:
  2.     offscreen support library
  3.     by Cary Clark, Georgiann Delaney, Michael Fairman, Dave Good, Robert Johnson, Keith McGreggor, Oliver Steele, David Van Brink, Chris Yerga
  4.     Copyright 1987 - 1991 Apple Computer, Inc.  All rights reserved. */
  5.  
  6. #ifndef powerc
  7.  #pragma pointers_in_D0                            
  8. #endif
  9.  
  10. #include <Memory.h>
  11.  
  12. #ifndef powerc
  13.  #pragma pointers_in_A0
  14. #endif
  15.  
  16. #include "graphics libraries.h"
  17. #include "offscreen library.h"
  18.  
  19.  
  20. typedef struct viewPortBufferRecord {
  21.     gxViewPort    masterPort;
  22.     gxViewPort    slavePort;
  23.     gxShape        area;
  24.     gxShape        draw;
  25.     gxViewGroup    group;
  26.     long            deviceCount;
  27.     gxViewDevice    devices[1];
  28. } viewPortBufferRecord;
  29.  
  30. static void ClearBytes(void *block, register long length)
  31. {
  32.     register char *b = (char *) block;
  33.     
  34.     do
  35.         *b++ = 0;
  36.     while (--length);
  37. }
  38.  
  39. /*
  40.     Given a gxBitmap gxShape, this routine fills out the offscreen structure with the objects necessary to draw into
  41.     the offscreen and transfer the offscreen onscreen.  See the header file for details about the offscreen structure.
  42. */
  43. void CreateOffscreen(register offscreen *os, gxShape bitShape)
  44. {
  45.     NilParamReturn(os);
  46.     ClearBytes(os, sizeof(offscreen));
  47.     NilShapeReturn(bitShape);
  48.     os->group = GXNewViewGroup();
  49.     os->device = GXNewViewDevice(os->group, bitShape);
  50.     os->port = GXNewViewPort(os->group);
  51.     os->draw = GXGetViewDeviceBitmap(os->device);        /* draw this gxShape to copy the offscreen to the screen */
  52.     os->xform = GXNewTransform();                /* assign this to shapes and they will draw offscreen */
  53.     GXSetTransformViewPorts(os->xform, 1, &os->port);
  54. }
  55.  
  56.  
  57. /*
  58.     When you're done with the offscreen, call this routine.
  59. */
  60. void DisposeOffscreen(offscreen *os)
  61. {
  62.     NilParamReturn(os);
  63.     GXDisposeShape(os->draw);        /* dispense with gxBitmap gxShape */
  64.     GXDisposeTransform(os->xform);    /* …and gxTransform */
  65.     GXDisposeViewGroup(os->group);    /* …and gxViewGroup (which disposes gxViewPort and gxViewDevice) */
  66. }
  67.  
  68.  
  69. void CopyToBitmaps(gxShape dest, gxShape source)
  70. {
  71.     offscreen destOff;
  72.     
  73.     NilShapeReturn(dest);
  74.     NilShapeReturn(source);
  75.     CreateOffscreen(&destOff, dest);
  76.     {    long portCount = GXGetShapeViewPorts(source, nil);
  77.         gxViewPort *savedPorts = (gxViewPort *) NewPtr(sizeof(gxViewPort) * portCount);
  78.         
  79.         GXGetShapeViewPorts(source, savedPorts);
  80.         GXSetShapeViewPorts(source, 1, &destOff.port);
  81.         GXDrawShape(source);
  82.         GXSetShapeViewPorts(source, portCount, savedPorts);
  83.         DisposePtr((Ptr) savedPorts);
  84.     }
  85.     DisposeOffscreen(&destOff);
  86. }
  87.  
  88. typedef struct {
  89.     gxBitmap    bits;
  90.     gxPoint        offset;
  91. } areaCharacteristics;
  92.  
  93. static areaCharacteristics GetAreaCharacteristics(gxShape area, gxViewDevice device, gxViewPort port)
  94. {
  95.     areaCharacteristics x;
  96.     gxRectangle bounds;
  97.     gxShape bitShape;
  98.     gxMapping map;
  99.  
  100.     ClearBytes(&x, sizeof(x));
  101.     ClearBytes(&bounds, sizeof(bounds));
  102.     ClearBytes(&map, sizeof(map));
  103.     bitShape = GXGetViewDeviceBitmap(device);
  104.     GXGetShapeGlobalBounds(area, port, nil, &bounds);
  105.     GXGetBitmap(bitShape, &x.bits, nil);
  106.     if (x.bits.space == gxIndexedSpace)
  107.         GXCloneColorSet(x.bits.set);
  108.     if (x.bits.profile)
  109.         GXCloneColorProfile(x.bits.profile);
  110.     GXDisposeShape(bitShape);
  111.     x.offset.x = bounds.left;
  112.     x.offset.y = bounds.top;
  113.     x.bits.width = FixedRound(bounds.right) - FixedRound(bounds.left);
  114.     x.bits.height = FixedRound(bounds.bottom) - FixedRound(bounds.top);
  115.     InvertMapping(&map, GXGetViewPortGlobalMapping(port, &map));
  116.     MapPoints(&map, 1, &x.offset);
  117.     return x;
  118. }
  119.  
  120. static void DisposeAreaCharacteristics(areaCharacteristics *x)
  121. {
  122.     if (x->bits.space == gxIndexedSpace)
  123.         GXDisposeColorSet(x->bits.set);
  124.     if (x->bits.profile)
  125.         GXDisposeColorProfile(x->bits.profile);
  126. }
  127.  
  128. static gxViewDevice NewDeviceWithAreaCharacteristics(gxViewGroup group, areaCharacteristics *x)
  129. {
  130.     gxViewDevice device;
  131.     gxShape bitShape;
  132.     gxMapping map;
  133.  
  134.     NilParamReturnNil(x);
  135.     bitShape = GXNewBitmap(&x->bits, nil);
  136.     device = GXNewViewDevice(group, bitShape);
  137.     GXDisposeShape(bitShape);
  138.     ResetMapping(&map);
  139.     MoveMapping(&map, -x->offset.x, -x->offset.y);
  140.     GXSetViewDeviceMapping(device, &map);
  141.     return device;
  142. }
  143.  
  144. static areaCharacteristics GetDeviceAreaCharacteristics(gxViewDevice device)
  145. {
  146.     areaCharacteristics x;
  147.     gxShape bitShape;
  148.     gxMapping map;
  149.  
  150.     ClearBytes(&x, sizeof(x));
  151.     ClearBytes(&map, sizeof(map));
  152.     bitShape = GXGetViewDeviceBitmap(device);
  153.     GXGetBitmap(bitShape, &x.bits, nil);
  154.     if (x.bits.space == gxIndexedSpace)
  155.         GXCloneColorSet(x.bits.set);
  156.     if (x.bits.profile)
  157.         GXCloneColorProfile(x.bits.profile);
  158.     GXDisposeShape(bitShape);
  159.     GXGetViewDeviceMapping(device, &map);
  160.     x.offset.x = -map.map[2][0];
  161.     x.offset.y = -map.map[2][1];
  162.     return x;
  163. }
  164.  
  165. static void SetDeviceAreaCharacteristics(gxViewDevice device, areaCharacteristics *x)
  166. {
  167.     gxShape bitShape;
  168.     gxBitmap bits;
  169.     gxMapping map;
  170.  
  171.     NilParamReturn(x);
  172.     bits.width = 1;
  173.     bits.height = 1;
  174.     bits.pixelSize = 1;
  175.     bits.rowBytes = 0;
  176.     bits.image = nil;
  177.     bits.space = gxIndexedSpace;
  178.     bits.set = nil;
  179.     bits.profile = nil;
  180.     bitShape = GXNewBitmap(&bits, nil);
  181.     GXSetViewDeviceBitmap(device, bitShape);
  182.     GXDisposeShape(bitShape);
  183.  
  184.     bitShape = GXNewBitmap(&x->bits, nil);
  185.     GXSetViewDeviceBitmap(device, bitShape);
  186.     GXDisposeShape(bitShape);
  187.     ResetMapping(&map);
  188.     MoveMapping(&map, -x->offset.x, -x->offset.y);
  189.     GXSetViewDeviceMapping(device, &map);
  190. }
  191.  
  192. static boolean EqualAreaCharacteristics(areaCharacteristics *x, areaCharacteristics *y)
  193. {
  194.     NilParamReturnNil(x);
  195.     NilParamReturnNil(y);
  196.     return x->bits.space == y->bits.space
  197.         && x->bits.set == y->bits.set
  198.         && x->bits.profile == y->bits.profile
  199.         && x->offset.x == y->offset.x
  200.         && x->offset.y == y->offset.y
  201.         && x->bits.width == y->bits.width
  202.         && x->bits.height == y->bits.height
  203.         && x->bits.pixelSize == y->bits.pixelSize;
  204. }
  205.  
  206. static void AddBitmapShapes(viewPortBufferRecord *buffers)
  207. {
  208.     short i;
  209.  
  210.     NilParamReturn(buffers);
  211.     for (i = 0; i < buffers->deviceCount; i++) 
  212.     {    gxViewDevice device = buffers->devices[i];
  213.         gxShape bitShape = GXGetViewDeviceBitmap(device);
  214.         gxMapping map;
  215.     
  216.         ClearBytes(&map, sizeof(map));
  217.         GXGetViewDeviceMapping(device, &map);
  218.         GXSetShapeAttributes(bitShape, GXGetShapeAttributes(bitShape) | gxMapTransformShape);
  219.         GXMoveShape(bitShape, -map.map[2][0], -map.map[2][1]);
  220.         GXSetShapeParts(buffers->draw, 0, 0, bitShape, 0);
  221.         GXDisposeShape(bitShape);
  222.     }
  223. }
  224.  
  225. viewPortBuffer NewViewPortBuffer(gxViewPort port)
  226. {
  227.     viewPortBuffer buffersHandle;
  228.     viewPortBufferRecord *buffers;
  229.     gxTransform xform;
  230.     gxShape area;
  231.     long deviceCount;
  232.     short i;
  233.  
  234.     NilParamReturnNil(port);
  235.     area = GXNewShape(gxFullType);
  236.     xform = GXNewTransform();
  237.     GXSetTransformViewPorts(xform, 1, &port);
  238.     GXSetShapeTransform(area, xform);
  239.     GXDisposeTransform(xform);
  240.     deviceCount = GXGetShapeGlobalViewDevices(area, port, nil);
  241.     buffersHandle = (viewPortBuffer) NewHandle(sizeof(viewPortBufferRecord) + (deviceCount - 1) * sizeof(gxViewDevice));
  242.     NilParamReturnNil(buffersHandle);
  243.     HLock((Handle) buffersHandle);
  244.     buffers = *buffersHandle;
  245.     buffers->group = GXNewViewGroup();
  246.     buffers->masterPort = port;
  247.     buffers->slavePort = GXNewViewPort(buffers->group);
  248.     buffers->area = area;
  249.     buffers->draw = GXNewShape(gxPictureType);
  250.     buffers->deviceCount = deviceCount;
  251.     GXSetViewPortDither(buffers->slavePort, GXGetViewPortDither(port));
  252.     GXGetShapeGlobalViewDevices(area, port, buffers->devices);
  253.     for (i = 0; i < deviceCount; i++) 
  254.     {    gxViewDevice device = buffers->devices[i];
  255.         areaCharacteristics x = GetAreaCharacteristics(area, device, port);
  256.     
  257.         buffers->devices[i] = NewDeviceWithAreaCharacteristics(buffers->group, &x);
  258.         DisposeAreaCharacteristics(&x);
  259.     }
  260.     AddBitmapShapes(buffers);
  261.     HUnlock((Handle) buffersHandle);
  262.     return buffersHandle;
  263. }
  264.  
  265. void DisposeViewPortBuffer(viewPortBuffer buffersHandle)
  266. {
  267.     NilParamReturn(buffersHandle);
  268.     GXDisposeShape((*buffersHandle)->area);
  269.     GXDisposeShape((*buffersHandle)->draw);
  270.     GXDisposeViewGroup((*buffersHandle)->group);
  271.     DisposeHandle((Handle) buffersHandle);
  272. }
  273.  
  274. boolean ValidViewPortBuffer(viewPortBuffer buffersHandle)
  275. {
  276.     long deviceCount;
  277.     gxViewDevice *devices;
  278.     boolean valid = true;
  279.     short i;
  280.  
  281.     NilParamReturnNil(buffersHandle);
  282.     deviceCount = GXGetShapeGlobalViewDevices((*buffersHandle)->area, (*buffersHandle)->masterPort, nil);
  283.     if (deviceCount != (*buffersHandle)->deviceCount)
  284.         return false;
  285.     devices = (gxViewDevice *) NewPtr(deviceCount * sizeof(gxViewDevice));
  286.     NilParamReturnNil(devices);
  287.     for (i = 0; i < deviceCount; i++) 
  288.     {    areaCharacteristics x = GetAreaCharacteristics((*buffersHandle)->area, devices[i], (*buffersHandle)->masterPort);
  289.         areaCharacteristics y = GetDeviceAreaCharacteristics((*buffersHandle)->devices[i]);
  290.     
  291.         valid = EqualAreaCharacteristics(&x, &y);
  292.         DisposeAreaCharacteristics(&x);
  293.         DisposeAreaCharacteristics(&y);
  294.         if (!valid) break;
  295.     }
  296.     DisposePtr((Ptr) devices);
  297.     return valid;
  298. }
  299.  
  300. boolean UpdateViewPortBuffer(viewPortBuffer buffersHandle)
  301. {
  302.     viewPortBufferRecord *buffers;
  303.     short state;
  304.     long deviceCount;
  305.     gxViewDevice *devices;
  306.     boolean valid = true;
  307.     short i;
  308.  
  309.     NilParamReturnNil(buffersHandle);
  310.     state = HGetState((Handle) buffersHandle);
  311.     HLock((Handle) buffersHandle);
  312.     buffers = *buffersHandle;
  313.     deviceCount = GXGetShapeGlobalViewDevices(buffers->area, buffers->masterPort, nil);
  314.     if (deviceCount != buffers->deviceCount) {
  315.         valid = false;
  316.         GXSetPicture(buffers->draw, 0, nil, nil, nil, nil);
  317.         if (deviceCount < buffers->deviceCount) {
  318.             for (i = deviceCount; i < buffers->deviceCount; i++)
  319.                 GXDisposeViewDevice(buffers->devices[i]);
  320.             SetHandleSize((Handle) buffersHandle, sizeof(viewPortBufferRecord) + (deviceCount - 1) * sizeof(gxViewDevice));
  321.             buffers = *buffersHandle;
  322.         } else {
  323.             HUnlock((Handle) buffersHandle);
  324.             SetHandleSize((Handle) buffersHandle, sizeof(viewPortBufferRecord) + (deviceCount - 1) * sizeof(gxViewDevice));
  325.             HLock((Handle) buffersHandle);
  326.             buffers = *buffersHandle;
  327.             for (i = buffers->deviceCount; i < deviceCount; i++)
  328.                 buffers->devices[i] = nil;
  329.         }
  330.         buffers->deviceCount = deviceCount;
  331.     }
  332.     devices = (gxViewDevice *) NewPtr(deviceCount * sizeof(gxViewDevice));
  333.     NilParamReturnNil(devices);
  334.     deviceCount = GXGetShapeGlobalViewDevices(buffers->area, buffers->masterPort, devices);
  335.     for (i = 0; i < deviceCount; i++) 
  336.     {    gxViewDevice device = buffers->devices[i];
  337.         areaCharacteristics x = GetAreaCharacteristics(buffers->area, devices[i], buffers->masterPort);
  338.     
  339.         if (device) 
  340.         {    areaCharacteristics y = GetDeviceAreaCharacteristics(device);
  341.         
  342.             if (EqualAreaCharacteristics(&x, &y) == false) {
  343.                 valid = false;
  344.                 GXSetPicture(buffers->draw, 0, nil, nil, nil, nil);
  345.                 SetDeviceAreaCharacteristics(device, &x);
  346.             }
  347.             DisposeAreaCharacteristics(&y);
  348.         } else
  349.             buffers->devices[i] = NewDeviceWithAreaCharacteristics(buffers->group, &x);
  350.         DisposeAreaCharacteristics(&x);
  351.     }
  352.     DisposePtr((Ptr) devices);
  353.     if (valid == false)
  354.         AddBitmapShapes(buffers);
  355.     HSetState((Handle) buffersHandle, state);
  356.     return valid;
  357. }
  358.  
  359. gxViewPort GetViewPortBufferViewPort(viewPortBuffer buffersHandle)
  360. {
  361.     NilParamReturnNil(buffersHandle);
  362.     return (*buffersHandle)->slavePort;
  363. }
  364.  
  365. gxShape GetViewPortBufferShape(viewPortBuffer buffersHandle)
  366. {
  367.     NilParamReturnNil(buffersHandle);
  368.     return (*buffersHandle)->draw;
  369. }
  370.